import { NextRequest, NextResponse } from 'next/server';
import { GloableResponseItem, ResponseEnum } from '@/utils/request/res';
import { Auth, type ExtendedNextApiRequest, ResponseHandler, LogOperation } from '@/utils/decorator';
import prisma from '@/utils/db/PrismaService';
import { BaseController } from '@/utils/request/BaseController';
import { GET as HttpGet, POST as HttpPost, PUT as HttpPut, DELETE as HttpDelete } from '@/utils/decorator';
import { createAllMethodHandlers } from '@/utils/request/routeRegistry';
import dayjs from 'dayjs';

/**
 * 构建树形结构
 * @param items 菜单列表
 * @param parentId 父菜单ID
 * @returns 树形结构
 */
const buildTree = (items: any[], parentId: number | null = 0): any[] => { 
    return items
        .filter(item => item.parent_id === parentId)
        .map(item => ({
            ...item,
            children: buildTree(items, item.id)
        }))
        .sort((a, b) => a.sort_order - b.sort_order);
};

class SystemMenuController extends BaseController {

    /**
     * 获取菜单列表（树形结构）
     */
    @Auth()
    @ResponseHandler()
    @HttpGet()
    static async getMenuList(request: ExtendedNextApiRequest) {
        // 查询所有未删除的菜单项
        const menuList = await prisma.sysMenu.findMany({
            where: {
                del_flag: 1,
            },
            orderBy: [
                {
                    parent_id: 'asc',
                },
                {
                    sort_order: 'asc',
                }
            ],
        });

        const menuTree = buildTree(menuList);
        return GloableResponseItem(ResponseEnum.success, "获取成功", menuTree);
    }

    /**
     * 获取所有菜单（平铺结构）
     */
    @Auth()
    @ResponseHandler()
    @HttpGet()
    static async getMenuAll(request: ExtendedNextApiRequest) {
        const menuList = await prisma.sysMenu.findMany({
            where: {
                del_flag: 1,
            },
            orderBy: [
                {
                    sort_order: 'asc',
                }
            ],
        });
        return GloableResponseItem(ResponseEnum.success, "获取成功", menuList);
    }

    /**
     * 获取用户菜单
     */
    @Auth()
    @ResponseHandler()
    @HttpGet()
    static async getUserMenu(request: ExtendedNextApiRequest) {
        const { userType, roleType } = request.customBody;

        // 查询适用于该用户类型和角色的菜单
        let menuList = await prisma.sysMenu.findMany({
            where: {
                del_flag: 1,
                status: 1,
                visible: true,
                OR: [
                    {
                        // 用户类型匹配
                        user_types: {
                            contains: userType
                        }
                    },
                    {
                        // 角色类型匹配
                        role_types: {
                            contains: roleType
                        }
                    },
                    {
                        // 超级管理员用户可以看到全部菜单
                        user_types: userType === "00" ? {} : undefined
                    }
                ]
            },
            orderBy: [
                {
                    parent_id: 'asc',
                },
                {
                    sort_order: 'asc',
                }
            ],
        });

        // 处理权限字段，将JSON字符串转换为数组
        menuList = menuList.map((menu: any) => ({
            ...menu,
            permissions: menu.permissions ? JSON.parse(menu.permissions) : [],
            user_types: menu.user_types ? JSON.parse(menu.user_types) : [],
            role_types: menu.role_types ? JSON.parse(menu.role_types) : [],
        }));

        const menuTree = buildTree(menuList);
        return GloableResponseItem(ResponseEnum.success, "获取成功", menuTree);
    }

    /**
     * 添加菜单
     */
    @Auth()
    @ResponseHandler()
    @HttpPost()
    @LogOperation({ module: "菜单管理", operationName: "添加菜单" })
    static async addMenu(request: ExtendedNextApiRequest) {
        const body = request.customBody;
        const now = dayjs().format("YYYY-MM-DD HH:mm:ss");

        // 检查menu_key是否已存在
        const existingMenu = await prisma.sysMenu.findUnique({
            where: {
                menu_key: body.menu_key,
                del_flag: 1,
            },
        });

        if (existingMenu) {
            return GloableResponseItem(ResponseEnum.fail, "菜单标识已存在，请重新输入", null);
        }

        const menuData = {
            ...body,
            permissions: body.permissions ? JSON.stringify(body.permissions) : null,
            user_types: body.user_types ? JSON.stringify(body.user_types) : null,
            role_types: body.role_types ? JSON.stringify(body.role_types) : null,
            create_time: now,
            update_time: now,
            del_flag: 1
        };
        try {
            const result = await prisma.sysMenu.create({
                data: menuData
            });
            return GloableResponseItem(ResponseEnum.success, "添加成功", result);
        } catch (error) {
            return GloableResponseItem(ResponseEnum.fail, "添加失败", null);
        }
    }

    /**
     * 更新菜单
     */
    @Auth()
    @ResponseHandler()
    @HttpPut()
    @LogOperation({ module: "菜单管理", operationName: "更新菜单" })
    static async updateMenu(request: ExtendedNextApiRequest) {
        const { id, ...updateData } = request.customBody;
        if (!id) {
            return GloableResponseItem(ResponseEnum.fail, "缺少菜单ID", null);
        }

        const existingMenu = await prisma.sysMenu.findUnique({
            where: { id: id }
        });

        if (existingMenu?.is_fixed && updateData.status === 0) {
            return GloableResponseItem(ResponseEnum.fail, "固定菜单不能禁用", null);
        }

        const menuData = {
            ...updateData,
            permissions: updateData.permissions ? JSON.stringify(updateData.permissions) : null,
            user_types: updateData.user_types ? JSON.stringify(updateData.user_types) : null,
            role_types: updateData.role_types ? JSON.stringify(updateData.role_types) : null,
            update_time: dayjs().format("YYYY-MM-DD HH:mm:ss")
        };

        const result = await prisma.sysMenu.update({
            where: { id: id },
            data: menuData
        });

        return GloableResponseItem(ResponseEnum.success, "更新成功", result);
    }

    /**
     * 删除菜单
     */
    @Auth()
    @ResponseHandler()
    @HttpDelete()
    @LogOperation({ module: "菜单管理", operationName: "删除菜单" })
    static async deleteMenu(request: ExtendedNextApiRequest) {
        const { id } = request.customBody;

        if (!id) {
            return GloableResponseItem(ResponseEnum.fail, "缺少菜单ID", null);
        }

        const existingMenu = await prisma.sysMenu.findUnique({
            where: { id: id }
        });

        if (existingMenu?.is_fixed) {
            return GloableResponseItem(ResponseEnum.fail, "固定菜单不能删除", null);
        }

        const childCount = await prisma.sysMenu.count({
            where: {
                parent_id: id,
                del_flag: 1
            }
        });

        if (childCount > 0) {
            return GloableResponseItem(ResponseEnum.fail, "请先删除子菜单", null);
        }

        const result = await prisma.sysMenu.update({
            where: { id: id },
            data: {
                del_flag: 0,
                update_time: dayjs().format("YYYY-MM-DD HH:mm:ss")
            }
        });

        return GloableResponseItem(ResponseEnum.success, "删除成功", result);
    }
}

// 使用自动路由处理器创建所有HTTP方法处理函数
const handlers = createAllMethodHandlers(SystemMenuController);

export const { GET, POST, PUT, DELETE } = handlers;
